#ifndef OCEAN_VAGSDK_JNI_UTIL_H
#define OCEAN_VAGSDK_JNI_UTIL_H

#include <jni.h>
#include <string>

/**
 *
 * Converts jstring to cpp string.
 *
 * @param env the jni env pointer
 * @param jstr the jstring to be converted
 * @return the converted string
 */
std::string ConvertToStdString(JNIEnv *env, jstring jstr);

/**
 * Sets the str to specified obj with fieldID.
 *
 * @param env the jni env
 * @param obj the obj to be sets
 * @param fieldID the fieldID belongs to obj
 * @param str the string will set to fieldID's value
 */
void SetObjectStringField(JNIEnv *env, jobject obj, jfieldID fieldID, const std::string& str);

jobject NewArrayList(JNIEnv *env);


class JNIHandle {
private:
    JNIHandle();

    ~JNIHandle();

public:
    void Init(JNIEnv *env);

    static JNIHandle *GetInstance();

    JavaVM *jvm;

    /** Boolean */
    jclass cls_boolean;
    jmethodID mid_boolean_init;

    /** Long */
    jclass cls_long;
    jfieldID fid_long_value;

    /** List */
    jclass cls_list;
    jmethodID mid_list_size;
    jmethodID mid_list_add;
    jmethodID mid_list_get;

    /** ArrayList */
    jclass cls_arraylist;
    jmethodID mid_arraylist_init;
    jmethodID mid_arraylist_add;

    /** VagApiException */
    jclass cls_vagApi_ex;

    /** ApiResult */
    jclass cls_apiResult;
    jmethodID mid_apiResult_init;

    /** DeviceInfo */
    jclass cls_deviceInfo;
    jmethodID mid_deviceInfo_init;
    jfieldID fid_deviceInfo_type;
    jfieldID fid_deviceInfoType_value;
    jfieldID fid_deviceInfoLinkMode;
    jfieldID fid_deviceInfoLinkMode_value;
    jfieldID fid_deviceInfo_dev_uuid;
    jfieldID fid_deviceInfo_ip;
    jfieldID fid_deviceInfo_port;
    jfieldID fid_deviceInfo_username;
    jfieldID fid_deviceInfo_password;

    /** DauDeviceInfo */
    jclass cls_dauDeviceInfo;
    jmethodID mid_dauDeviceInfo_init;
    jfieldID fid_dauDeviceInfo_name;
    jfieldID fid_dauDeviceInfo_serialnum;
    jfieldID fid_dauDeviceInfo_version;
    jfieldID fid_dauDeviceInfo_devType;

    /** DevChannelInfo */
    jclass cls_devChannelInfo;
    jmethodID mid_devChannelInfo_init;
    jfieldID fid_devChannelInfo_channelNum;
    jfieldID fid_devChannelInfo_channelNameInfo;

    /** ChannelNameInfo */
    jclass cls_channelNameInfo;
    jmethodID mid_channelNameInfo_init;
    jfieldID fid_channelNameInfo_name;
    jfieldID fid_channelNameInfo_index;
    jfieldID fid_channelNameInfo_remoteIndex;

    /** ShowStringInfo */
    jclass cls_showStringInfo;
    jmethodID mid_showStringInfo_init;
    jfieldID fid_showStringInfo_osdInfoList;

    /** OsdInfo */
    jclass cls_osdInfo;
    jmethodID mid_osdInfo_init;
    jfieldID fid_osdInfo_iShowString;
    jfieldID fid_osdInfo_iStringSize;
    jfieldID fid_osdInfo_iShowStringTopLeftX;
    jfieldID fid_osdInfo_iShowStringTopLeftY;
    jfieldID fid_osdInfo_text;

    /** SetUpAlarm */
    jclass cls_setUpAlarm;
    jmethodID mid_setUpAlarm_init;
    jfieldID fid_setUpAlarm_dwSize;
    jfieldID fid_setUpAlarm_byLevel;
    jfieldID fid_setUpAlarm_byAlarmInfoType;
    jfieldID fid_setUpAlarm_byRetAlarmTypeV40;
    jfieldID fid_setUpAlarm_byRetVQDAlarmType;
    jfieldID fid_setUpAlarm_byRetDevInfoVersion;
    jfieldID fid_setUpAlarm_byFaceAlarmDetection;
    jfieldID fid_setUpAlarm_bySupport;
    jfieldID fid_setUpAlarm_byBrokenNetHttp;
    jfieldID fid_setUpAlarm_wTaskNo;
    jfieldID fid_setUpAlarm_byDeployType;
    jfieldID fid_setUpAlarm_bySubScription;
    jfieldID fid_setUpAlarm_byBrokenNetHttpV60;
    jfieldID fid_setUpAlarm_byRes1;
    jfieldID fid_setUpAlarm_byAlarmTypeURL;
    jfieldID fid_setUpAlarm_byCustomCtrl;
    jfieldID fid_setUpAlarm_byRes4;

    /** VagApi */
    jclass cls_vagApi;
    jmethodID mid_vagApi_alarmCallback;


};

#endif //OCEAN_VAGSDK_JNI_UTIL_H
